##
# This controller handles taken exams for students
class TakeExamController < ApplicationController
	helper :paginator
	helper :right
	include PaginatorHelper
	include RightHelper
	layout 'scaffold'

  # only students may access this controller
	before_filter :verify_student
  # exams must be submitted in time
  before_filter :verify_time, :only => [ :submit_exam ]

  ##
  # redirects to list
	def index
		list 
		render :action => 'list'
	end
	
  # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
  verify :method => :post, :only => [ :destroy, :create, :update ],
         :redirect_to => { :action => :list }

	verify :session => 'user',
				 :add_flash => {:error => 'you must be logged in to create activations'},
				 :redirect_to => { :controller => 'user', :action => :login }

  ##
  # displays all activated exams.
	def list
		t = Time.new
		group = session['user'].group
		activations = group.activations
		@exams = activations.collect do |a| 
			if(a.start < t && a.end > t)
				a.exam 
			else
				nil
			end
		end
		@exams = @exams.compact
		@exams = @exams.uniq
		@exam_pages, @exams = paginate_collection @exams, :per_page => 10,
                                                      :page => params[:page]
	end

  ##
  # creates the take-exam-form
	def take
		@exam = Exam.find(params[:id])
	end

  ##
  # stores the result for the exam in the DB
	def submit_exam
		exam = Exam.find(params[:id])
		time = Time.new
    
    score = 0
    max_score = 0
    
		exam.questions.each do |q|
      max_score += q.score
      correct = true
      
			q.answers.each do |a|
				user_answer = UserAnswer.new
				user_answer.answer = a
				user_answer.user = session['user']
				user_answer.time = time
        
				# check with elements are selected, and insert into db
				if((!params['a_' + q.id.to_s].nil?) && 
					 params['a_' + q.id.to_s].include?(a.id.to_s))
					user_answer.correctness = 1
				else 
					user_answer.correctness = 0
				end
        
        if(user_answer.correctness != a.correctness)
          correct = false
        end
				user_answer.save
			end
      
      if correct
        score += q.score
      end
		end
    
    # creating the redundant result for faster DB-Access
    result = ExamResult.new
    result.exam = exam
    result.user = session['user']
    result.score = score
    result.max_score = max_score
    result.time = time
    result.save
    
		flash[:notice] = 'Exam was successfully submittet.'
		redirect_to :action => 'index'
	end
  
  private 
  ##
  # verifies that the submitted exam was submitted in time 
  def verify_time
    t = Time.new
    exam = Exam.find(params[:id])
    activations = Activation.find(:all, :conditions => 
                                  [ "exam_id = ? and ? between start and end",
                                     exam.id, t.to_s(:db) ])
    if(activations.size == 0)
      flash[:error] = "Sorry, the exam isn't active anymore"
      redirect_to :action => "list"
    end
    # check whether the exam was taken twice
    results = ExamResult.find(:all, :conditions => { :exam_id => exam.id, 
                                                     :user_id => session['user']
                                                   })
    recent = Array.new
    activations = activations.sort_by { |a| a.start }
    results = results.sort_by { |r| r.time }
    for a in activations
      to_delete = nil
      for r in results
        if(r.time > a.start && r.time < a.end)
          recent << r
          to_delete = r
          break
        end
      end
      results.delete(to_delete) if !to_delete.nil?
    end
    
    if((activations.size - recent.size) < 1)
      flash[:error] = "Sorry, but you have no free activations for this exam "\
                      "anymore"
      redirect_to :action => 'list'
    end
  end
end

